diff --git a/test_cases/README.md b/test_cases/README.md deleted file mode 100644 index 2f06b41..0000000 --- a/test_cases/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# Modern E-Commerce Store - -A production-ready e-commerce application with responsive design, authentication, and full shopping functionality. - -## Features - -- Responsive UI with mobile-first design -- Homepage with hero section and featured products -- Category browsing -- Product cards with images and details -- Product detail page -- Shopping cart functionality -- Checkout form with validation -- Authentication pages (login/signup) -- Reusable React components -- Mock backend/data layer -- Clean, modern styling -- Context API for state management - -## Tech Stack - -- React.js (with hooks and context API) -- React Router for navigation -- CSS Modules for styling -- LocalStorage for data persistence -- Mock API for backend simulation - -## Getting Started - -### Prerequisites - -- Node.js (v14 or later) -- npm or yarn - -### Installation - -1. Clone the repository -2. Install dependencies: - ```bash - npm install - ``` -3. Start the development server: - ```bash - npm start - ``` - -### Running the Application - -The app will be available at http://localhost:3000 - -## Project Structure - -``` -src/ -├── components/ -│ ├── Header/ -│ ├── Footer/ -│ ├── Hero/ -│ ├── ProductCard/ -│ ├── Category/ -│ ├── CartItem/ -│ └── ProductList/ -├── pages/ -│ ├── Home/ -│ ├── Products/ -│ ├── ProductDetail/ -│ ├── Cart/ -│ ├── Checkout/ -│ ├── Login/ -│ └── Register/ -├── context/ -│ ├── AuthContext.js -│ └── CartContext.js -├── styles/ -│ └── globals.css -└── App.js -``` - -## Development - -This project was built with modern React practices including: -- Component-based architecture -- Context API for state management -- Responsive design principles -- Form validation -- Mock data layer for demonstration - -## Deployment - -To build for production: -```bash -npm run build -``` - -The build artifacts will be stored in the `build` folder. - -## License - -This project is licensed under the MIT License. \ No newline at end of file diff --git a/test_cases/package.json b/test_cases/package.json deleted file mode 100644 index e9caf3e..0000000 --- a/test_cases/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "modern-ecommerce-store", - "version": "1.0.0", - "description": "A production-ready e-commerce application", - "main": "index.js", - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.8.0", - "react-scripts": "5.0.1" - }, - "devDependencies": { - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} \ No newline at end of file diff --git a/test_cases/src/App.js b/test_cases/src/App.js deleted file mode 100644 index 05b6bd7..0000000 --- a/test_cases/src/App.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; -import './styles/globals.css'; -import Header from './components/Header/Header'; -import Footer from './components/Footer/Footer'; -import Home from './pages/Home/Home'; -import Products from './pages/Products/Products'; -import ProductDetail from './pages/ProductDetail/ProductDetail'; -import Cart from './pages/Cart/Cart'; -import Checkout from './pages/Checkout/Checkout'; -import Login from './pages/Login/Login'; -import Register from './pages/Register/Register'; -import { AuthProvider } from './context/AuthContext'; -import { CartProvider } from './context/CartContext'; - -function App() { - return ( - - - -
-
-
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - -
-
-
-
-
- ); -} - -export default App; \ No newline at end of file diff --git a/test_cases/src/components/CartItem/CartItem.css b/test_cases/src/components/CartItem/CartItem.css deleted file mode 100644 index b8b38ef..0000000 --- a/test_cases/src/components/CartItem/CartItem.css +++ /dev/null @@ -1,84 +0,0 @@ -.cart-item { - display: flex; - align-items: center; - border: 1px solid #ddd; - border-radius: 8px; - padding: 1rem; - margin-bottom: 1rem; - background-color: white; -} - -.cart-item-image { - width: 100px; - height: 100px; - object-fit: cover; - border-radius: 4px; - margin-right: 1rem; -} - -.cart-item-details { - flex: 1; -} - -.cart-item-name { - margin: 0 0 0.5rem 0; - color: #333; -} - -.cart-item-price { - margin: 0 0 1rem 0; - font-weight: bold; - color: #007bff; -} - -.quantity-controls { - display: flex; - align-items: center; - gap: 0.5rem; -} - -.quantity-btn { - width: 30px; - height: 30px; - border: 1px solid #ddd; - background-color: #f8f9fa; - border-radius: 4px; - cursor: pointer; - font-weight: bold; -} - -.quantity-btn:disabled { - opacity: 0.5; - cursor: not-allowed; -} - -.quantity { - min-width: 30px; - text-align: center; -} - -.remove-btn { - background-color: #dc3545; - color: white; - border: none; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - transition: background-color 0.3s; -} - -.remove-btn:hover { - background-color: #c82333; -} - -@media (max-width: 768px) { - .cart-item { - flex-direction: column; - text-align: center; - } - - .cart-item-image { - margin-right: 0; - margin-bottom: 1rem; - } -} \ No newline at end of file diff --git a/test_cases/src/components/CartItem/CartItem.jsx b/test_cases/src/components/CartItem/CartItem.jsx deleted file mode 100644 index a400197..0000000 --- a/test_cases/src/components/CartItem/CartItem.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import { useCart } from '../../context/CartContext'; -import './CartItem.css'; - -const CartItem = ({ item }) => { - const { updateQuantity, removeFromCart } = useCart(); - - const handleQuantityChange = (newQuantity) => { - if (newQuantity >= 1) { - updateQuantity(item.id, newQuantity); - } - }; - - return ( -
- {item.name} -
-

{item.name}

-

${item.price.toFixed(2)}

-
- - {item.quantity} - -
-
- -
- ); -}; - -export default CartItem; \ No newline at end of file diff --git a/test_cases/src/components/Category/Category.css b/test_cases/src/components/Category/Category.css deleted file mode 100644 index cbb26ac..0000000 --- a/test_cases/src/components/Category/Category.css +++ /dev/null @@ -1,39 +0,0 @@ -.category { - text-align: center; - margin: 1rem; -} - -.category-image img { - width: 150px; - height: 150px; - object-fit: cover; - border-radius: 50%; - border: 2px solid #ddd; - transition: transform 0.3s; -} - -.category-image img:hover { - transform: scale(1.05); -} - -.category-name { - margin-top: 0.5rem; - color: #333; - font-size: 1.1rem; -} - -.category a { - text-decoration: none; - color: inherit; -} - -@media (max-width: 768px) { - .category { - margin: 0.5rem; - } - - .category-image img { - width: 100px; - height: 100px; - } -} \ No newline at end of file diff --git a/test_cases/src/components/Category/Category.jsx b/test_cases/src/components/Category/Category.jsx deleted file mode 100644 index 5c151bb..0000000 --- a/test_cases/src/components/Category/Category.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import './Category.css'; - -const Category = ({ category }) => { - return ( -
- -
- {category.name} -
-

{category.name}

- -
- ); -}; - -export default Category; \ No newline at end of file diff --git a/test_cases/src/components/Footer/Footer.css b/test_cases/src/components/Footer/Footer.css deleted file mode 100644 index 92457f2..0000000 --- a/test_cases/src/components/Footer/Footer.css +++ /dev/null @@ -1,56 +0,0 @@ -.footer { - background-color: #333; - color: white; - margin-top: auto; -} - -.footer-container { - max-width: 1200px; - margin: 0 auto; - padding: 2rem; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 2rem; -} - -.footer-section h3 { - margin-bottom: 1rem; - color: #fff; -} - -.footer-section h4 { - margin-bottom: 1rem; - color: #fff; -} - -.footer-section ul { - list-style: none; - padding: 0; -} - -.footer-section ul li { - margin-bottom: 0.5rem; -} - -.footer-section ul li a { - color: #ccc; - text-decoration: none; - transition: color 0.3s; -} - -.footer-section ul li a:hover { - color: #fff; -} - -.footer-bottom { - text-align: center; - padding: 1rem; - border-top: 1px solid #555; -} - -@media (max-width: 768px) { - .footer-container { - grid-template-columns: 1fr; - text-align: center; - } -} \ No newline at end of file diff --git a/test_cases/src/components/Footer/Footer.jsx b/test_cases/src/components/Footer/Footer.jsx deleted file mode 100644 index 1d0d563..0000000 --- a/test_cases/src/components/Footer/Footer.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import './Footer.css'; - -const Footer = () => { - return ( - - ); -}; - -export default Footer; \ No newline at end of file diff --git a/test_cases/src/components/Header/Header.css b/test_cases/src/components/Header/Header.css deleted file mode 100644 index 0d0d666..0000000 --- a/test_cases/src/components/Header/Header.css +++ /dev/null @@ -1,85 +0,0 @@ -.header { - background-color: #fff; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - position: sticky; - top: 0; - z-index: 100; -} - -.header-container { - max-width: 1200px; - margin: 0 auto; - padding: 1rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.logo h2 { - color: #333; - text-decoration: none; -} - -.nav { - display: flex; - align-items: center; - gap: 1.5rem; -} - -.nav a { - text-decoration: none; - color: #333; - font-weight: 500; - transition: color 0.3s; -} - -.nav a:hover { - color: #007bff; -} - -.user-greeting { - font-weight: 500; - color: #333; -} - -.logout-btn { - background: none; - border: 1px solid #007bff; - color: #007bff; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - font-weight: 500; - transition: all 0.3s; -} - -.logout-btn:hover { - background-color: #007bff; - color: white; -} - -.auth-link { - background-color: #007bff; - color: white; - padding: 0.5rem 1rem; - border-radius: 4px; - text-decoration: none; - font-weight: 500; - transition: background-color 0.3s; -} - -.auth-link:hover { - background-color: #0056b3; -} - -@media (max-width: 768px) { - .header-container { - flex-direction: column; - gap: 1rem; - } - - .nav { - width: 100%; - justify-content: center; - } -} \ No newline at end of file diff --git a/test_cases/src/components/Header/Header.jsx b/test_cases/src/components/Header/Header.jsx deleted file mode 100644 index 2da8fe6..0000000 --- a/test_cases/src/components/Header/Header.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { useContext } from 'react'; -import { Link, useNavigate } from 'react-router-dom'; -import { AuthContext } from '../../context/AuthContext'; -import { useCart } from '../../context/CartContext'; -import './Header.css'; - -const Header = () => { - const { user, logout } = useContext(AuthContext); - const { getTotalItems } = useCart(); - const navigate = useNavigate(); - - const handleLogout = () => { - logout(); - navigate('/'); - }; - - return ( -
-
- -

ShopEasy

- - - -
-
- ); -}; - -export default Header; \ No newline at end of file diff --git a/test_cases/src/components/Hero/Hero.css b/test_cases/src/components/Hero/Hero.css deleted file mode 100644 index 1feb88b..0000000 --- a/test_cases/src/components/Hero/Hero.css +++ /dev/null @@ -1,57 +0,0 @@ -.hero { - background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('https://images.unsplash.com/photo-1607082350899-7e105aa886ae?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80'); - background-size: cover; - background-position: center; - height: 500px; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - color: white; - margin-bottom: 2rem; -} - -.hero-content { - max-width: 800px; - padding: 2rem; -} - -.hero-content h1 { - font-size: 3rem; - margin-bottom: 1rem; -} - -.hero-content p { - font-size: 1.2rem; - margin-bottom: 2rem; -} - -.cta-button { - display: inline-block; - background-color: #007bff; - color: white; - padding: 1rem 2rem; - border-radius: 4px; - text-decoration: none; - font-weight: bold; - font-size: 1.1rem; - transition: background-color 0.3s; -} - -.cta-button:hover { - background-color: #0056b3; -} - -@media (max-width: 768px) { - .hero { - height: 400px; - } - - .hero-content h1 { - font-size: 2rem; - } - - .hero-content p { - font-size: 1rem; - } -} \ No newline at end of file diff --git a/test_cases/src/components/Hero/Hero.jsx b/test_cases/src/components/Hero/Hero.jsx deleted file mode 100644 index 737ff0b..0000000 --- a/test_cases/src/components/Hero/Hero.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import './Hero.css'; - -const Hero = () => { - return ( -
-
-

Welcome to ShopEasy

-

Your one-stop destination for all your shopping needs

- - Shop Now - -
-
- ); -}; - -export default Hero; \ No newline at end of file diff --git a/test_cases/src/components/ProductCard/ProductCard.css b/test_cases/src/components/ProductCard/ProductCard.css deleted file mode 100644 index c90bac2..0000000 --- a/test_cases/src/components/ProductCard/ProductCard.css +++ /dev/null @@ -1,67 +0,0 @@ -.product-card { - border: 1px solid #ddd; - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); - transition: transform 0.3s, box-shadow 0.3s; - background-color: white; -} - -.product-card:hover { - transform: translateY(-5px); - box-shadow: 0 4px 16px rgba(0,0,0,0.15); -} - -.product-image { - width: 100%; - height: 200px; - object-fit: cover; -} - -.product-info { - padding: 1rem; -} - -.product-name { - margin: 0 0 0.5rem 0; - font-size: 1.2rem; - color: #333; -} - -.product-description { - color: #666; - font-size: 0.9rem; - margin-bottom: 1rem; - height: 60px; - overflow: hidden; -} - -.product-price { - font-size: 1.3rem; - font-weight: bold; - color: #007bff; - margin-bottom: 1rem; -} - -.view-details-btn { - display: block; - width: 100%; - text-align: center; - background-color: #007bff; - color: white; - padding: 0.75rem; - border-radius: 4px; - text-decoration: none; - font-weight: 500; - transition: background-color 0.3s; -} - -.view-details-btn:hover { - background-color: #0056b3; -} - -@media (max-width: 768px) { - .product-card { - margin-bottom: 1rem; - } -} \ No newline at end of file diff --git a/test_cases/src/components/ProductCard/ProductCard.jsx b/test_cases/src/components/ProductCard/ProductCard.jsx deleted file mode 100644 index 02a0c95..0000000 --- a/test_cases/src/components/ProductCard/ProductCard.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import './ProductCard.css'; - -const ProductCard = ({ product }) => { - return ( -
- {product.name} -
-

{product.name}

-

{product.description}

-
${product.price.toFixed(2)}
- - View Details - -
-
- ); -}; - -export default ProductCard; \ No newline at end of file diff --git a/test_cases/src/components/ProductList/ProductList.css b/test_cases/src/components/ProductList/ProductList.css deleted file mode 100644 index ed757ab..0000000 --- a/test_cases/src/components/ProductList/ProductList.css +++ /dev/null @@ -1,13 +0,0 @@ -.product-list { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 2rem; - margin: 2rem 0; -} - -@media (max-width: 768px) { - .product-list { - grid-template-columns: 1fr; - gap: 1rem; - } -} \ No newline at end of file diff --git a/test_cases/src/components/ProductList/ProductList.jsx b/test_cases/src/components/ProductList/ProductList.jsx deleted file mode 100644 index aa00cbd..0000000 --- a/test_cases/src/components/ProductList/ProductList.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import ProductCard from '../ProductCard/ProductCard'; -import './ProductList.css'; - -const ProductList = ({ products }) => { - if (!products || products.length === 0) { - return ( -
-

No products found.

-
- ); - } - - return ( -
- {products.map(product => ( - - ))} -
- ); -}; - -export default ProductList; \ No newline at end of file diff --git a/test_cases/src/context/AuthContext.js b/test_cases/src/context/AuthContext.js deleted file mode 100644 index ea6324a..0000000 --- a/test_cases/src/context/AuthContext.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, { createContext, useState, useContext } from 'react'; - -const AuthContext = createContext(); - -export const useAuth = () => { - const context = useContext(AuthContext); - if (!context) { - throw new Error('useAuth must be used within an AuthProvider'); - } - return context; -}; - -export const AuthProvider = ({ children }) => { - const [user, setUser] = useState(null); - - const login = (userData) => { - setUser(userData); - localStorage.setItem('user', JSON.stringify(userData)); - }; - - const logout = () => { - setUser(null); - localStorage.removeItem('user'); - }; - - const value = { - user, - login, - logout - }; - - return ( - - {children} - - ); -}; \ No newline at end of file diff --git a/test_cases/src/context/CartContext.js b/test_cases/src/context/CartContext.js deleted file mode 100644 index f5e3b42..0000000 --- a/test_cases/src/context/CartContext.js +++ /dev/null @@ -1,84 +0,0 @@ -import React, { createContext, useState, useContext, useEffect } from 'react'; - -const CartContext = createContext(); - -export const useCart = () => { - const context = useContext(CartContext); - if (!context) { - throw new Error('useCart must be used within a CartProvider'); - } - return context; -}; - -export const CartProvider = ({ children }) => { - const [cartItems, setCartItems] = useState([]); - - useEffect(() => { - const savedCart = localStorage.getItem('cartItems'); - if (savedCart) { - setCartItems(JSON.parse(savedCart)); - } - }, []); - - useEffect(() => { - localStorage.setItem('cartItems', JSON.stringify(cartItems)); - }, [cartItems]); - - const addToCart = (product, quantity = 1) => { - setCartItems(prevItems => { - const existingItem = prevItems.find(item => item.id === product.id); - - if (existingItem) { - return prevItems.map(item => - item.id === product.id - ? { ...item, quantity: item.quantity + quantity } - : item - ); - } else { - return [...prevItems, { ...product, quantity }]; - } - }); - }; - - const updateQuantity = (id, newQuantity) => { - if (newQuantity < 1) return; - - setCartItems(prevItems => - prevItems.map(item => - item.id === id ? { ...item, quantity: newQuantity } : item - ) - ); - }; - - const removeFromCart = (id) => { - setCartItems(prevItems => prevItems.filter(item => item.id !== id)); - }; - - const clearCart = () => { - setCartItems([]); - }; - - const getTotalItems = () => { - return cartItems.reduce((total, item) => total + item.quantity, 0); - }; - - const getTotalPrice = () => { - return cartItems.reduce((total, item) => total + (item.price * item.quantity), 0); - }; - - const value = { - cartItems, - addToCart, - updateQuantity, - removeFromCart, - clearCart, - getTotalItems, - getTotalPrice - }; - - return ( - - {children} - - ); -}; \ No newline at end of file diff --git a/test_cases/src/index.js b/test_cases/src/index.js deleted file mode 100644 index 5851d84..0000000 --- a/test_cases/src/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App'; - -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - - - -); \ No newline at end of file diff --git a/test_cases/src/pages/Cart/Cart.css b/test_cases/src/pages/Cart/Cart.css deleted file mode 100644 index 7343e01..0000000 --- a/test_cases/src/pages/Cart/Cart.css +++ /dev/null @@ -1,104 +0,0 @@ -.cart { - margin-bottom: 2rem; -} - -.cart-title { - text-align: center; - margin: 2rem 0; - color: #333; -} - -.cart-content { - display: grid; - grid-template-columns: 2fr 1fr; - gap: 2rem; -} - -.cart-items { - background-color: #f8f9fa; - padding: 1rem; - border-radius: 8px; -} - -.cart-summary { - background-color: white; - border: 1px solid #ddd; - border-radius: 8px; - padding: 1.5rem; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.summary-row { - display: flex; - justify-content: space-between; - margin-bottom: 1rem; - padding-bottom: 0.5rem; - border-bottom: 1px solid #eee; -} - -.summary-row.total { - font-weight: bold; - font-size: 1.2rem; - border-bottom: none; - margin-top: 1rem; - padding-top: 1rem; -} - -.checkout-btn { - width: 100%; - background-color: #28a745; - color: white; - border: none; - padding: 1rem; - border-radius: 4px; - font-size: 1.1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; - margin-top: 1rem; -} - -.checkout-btn:hover { - background-color: #218838; -} - -.cart-empty { - text-align: center; - padding: 3rem 0; -} - -.cart-empty h2 { - color: #333; - margin-bottom: 1rem; -} - -.cart-empty p { - color: #666; - margin-bottom: 2rem; -} - -.continue-shopping-btn { - background-color: #007bff; - color: white; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 4px; - font-size: 1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; -} - -.continue-shopping-btn:hover { - background-color: #0056b3; -} - -@media (max-width: 768px) { - .cart-content { - grid-template-columns: 1fr; - } - - .cart-summary { - order: -1; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/Cart/Cart.jsx b/test_cases/src/pages/Cart/Cart.jsx deleted file mode 100644 index e7f9200..0000000 --- a/test_cases/src/pages/Cart/Cart.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useCart } from '../../context/CartContext'; -import CartItem from '../../components/CartItem/CartItem'; -import './Cart.css'; - -const Cart = () => { - const { cartItems, getTotalPrice } = useCart(); - const navigate = useNavigate(); - - const total = getTotalPrice(); - - const handleCheckout = () => { - if (cartItems.length > 0) { - navigate('/checkout'); - } - }; - - if (cartItems.length === 0) { - return ( -
-
-

Your Cart is Empty

-

You haven't added any items to your cart yet.

- -
-
- ); - } - - return ( -
-
-

Your Shopping Cart

- -
-
- {cartItems.map(item => ( - - ))} -
- -
-

Order Summary

-
- Subtotal: - ${total.toFixed(2)} -
-
- Shipping: - Free -
-
- Total: - ${total.toFixed(2)} -
- -
-
-
-
- ); -}; - -export default Cart; \ No newline at end of file diff --git a/test_cases/src/pages/Checkout/Checkout.css b/test_cases/src/pages/Checkout/Checkout.css deleted file mode 100644 index 0aec2ad..0000000 --- a/test_cases/src/pages/Checkout/Checkout.css +++ /dev/null @@ -1,180 +0,0 @@ -.checkout { - margin-bottom: 2rem; -} - -.checkout-title { - text-align: center; - margin: 2rem 0; - color: #333; -} - -.checkout-content { - display: grid; - grid-template-columns: 2fr 1fr; - gap: 2rem; -} - -.checkout-form { - background-color: white; - border: 1px solid #ddd; - border-radius: 8px; - padding: 2rem; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.form-section { - margin-bottom: 2rem; -} - -.form-section h2 { - margin-top: 0; - margin-bottom: 1.5rem; - color: #333; - border-bottom: 1px solid #eee; - padding-bottom: 0.5rem; -} - -.form-row { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1rem; - margin-bottom: 1rem; -} - -.form-group { - margin-bottom: 1rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: #333; -} - -.form-group input { - width: 100%; - padding: 0.75rem; - border: 1px solid #ddd; - border-radius: 4px; - font-size: 1rem; -} - -.form-group input.error { - border-color: #dc3545; -} - -.error-message { - color: #dc3545; - font-size: 0.875rem; - margin-top: 0.25rem; - display: block; -} - -.submit-btn { - width: 100%; - background-color: #28a745; - color: white; - border: none; - padding: 1rem; - border-radius: 4px; - font-size: 1.1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; -} - -.submit-btn:hover:not(:disabled) { - background-color: #218838; -} - -.submit-btn:disabled { - background-color: #6c757d; - cursor: not-allowed; -} - -.order-summary { - background-color: #f8f9fa; - border: 1px solid #ddd; - border-radius: 8px; - padding: 1.5rem; -} - -.order-summary h2 { - margin-top: 0; - margin-bottom: 1.5rem; - color: #333; - border-bottom: 1px solid #eee; - padding-bottom: 0.5rem; -} - -.summary-items { - margin-bottom: 1.5rem; -} - -.summary-item { - display: flex; - justify-content: space-between; - padding: 0.5rem 0; - border-bottom: 1px solid #eee; -} - -.summary-total { - border-top: 1px solid #eee; - padding-top: 1rem; -} - -.total-row { - display: flex; - justify-content: space-between; - margin-bottom: 0.5rem; -} - -.grand-total { - font-weight: bold; - font-size: 1.1rem; - margin-top: 0.5rem; - padding-top: 0.5rem; - border-top: 1px solid #eee; -} - -.checkout-empty { - text-align: center; - padding: 3rem 0; -} - -.checkout-empty h2 { - color: #333; - margin-bottom: 1rem; -} - -.checkout-empty p { - color: #666; - margin-bottom: 2rem; -} - -.continue-shopping-btn { - background-color: #007bff; - color: white; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 4px; - font-size: 1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; -} - -.continue-shopping-btn:hover { - background-color: #0056b3; -} - -@media (max-width: 768px) { - .checkout-content { - grid-template-columns: 1fr; - } - - .form-row { - grid-template-columns: 1fr; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/Checkout/Checkout.jsx b/test_cases/src/pages/Checkout/Checkout.jsx deleted file mode 100644 index bb19022..0000000 --- a/test_cases/src/pages/Checkout/Checkout.jsx +++ /dev/null @@ -1,304 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; -import './Checkout.css'; - -const Checkout = () => { - const [cartItems, setCartItems] = useState([]); - const [total, setTotal] = useState(0); - const [formData, setFormData] = useState({ - firstName: '', - lastName: '', - email: '', - address: '', - city: '', - zipCode: '', - cardNumber: '', - expiryDate: '', - cvv: '' - }); - const [errors, setErrors] = useState({}); - const [isSubmitting, setIsSubmitting] = useState(false); - const navigate = useNavigate(); - - useEffect(() => { - const items = JSON.parse(localStorage.getItem('cartItems') || '[]'); - setCartItems(items); - const total = items.reduce((sum, item) => sum + (item.price * item.quantity), 0); - setTotal(total); - }, []); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData(prev => ({ - ...prev, - [name]: value - })); - - // Clear error when user starts typing - if (errors[name]) { - setErrors(prev => ({ - ...prev, - [name]: '' - })); - } - }; - - const validateForm = () => { - const newErrors = {}; - - if (!formData.firstName.trim()) { - newErrors.firstName = 'First name is required'; - } - - if (!formData.lastName.trim()) { - newErrors.lastName = 'Last name is required'; - } - - if (!formData.email.trim()) { - newErrors.email = 'Email is required'; - } else if (!/\S+@\S+\.\S+/.test(formData.email)) { - newErrors.email = 'Email is invalid'; - } - - if (!formData.address.trim()) { - newErrors.address = 'Address is required'; - } - - if (!formData.city.trim()) { - newErrors.city = 'City is required'; - } - - if (!formData.zipCode.trim()) { - newErrors.zipCode = 'ZIP code is required'; - } - - if (!formData.cardNumber.trim()) { - newErrors.cardNumber = 'Card number is required'; - } - - if (!formData.expiryDate.trim()) { - newErrors.expiryDate = 'Expiry date is required'; - } - - if (!formData.cvv.trim()) { - newErrors.cvv = 'CVV is required'; - } - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const handleSubmit = (e) => { - e.preventDefault(); - - if (validateForm()) { - setIsSubmitting(true); - - // Simulate API call - setTimeout(() => { - // Clear cart - localStorage.removeItem('cartItems'); - setIsSubmitting(false); - alert('Order placed successfully!'); - navigate('/'); - }, 1000); - } - }; - - if (cartItems.length === 0) { - return ( -
-
-

Empty Cart

-

Your cart is empty. Please add items before checking out.

- -
-
- ); - } - - return ( -
-
-

Checkout

- -
-
-
-

Shipping Information

-
-
- - - {errors.firstName && {errors.firstName}} -
- -
- - - {errors.lastName && {errors.lastName}} -
-
- -
- - - {errors.email && {errors.email}} -
- -
- - - {errors.address && {errors.address}} -
- -
-
- - - {errors.city && {errors.city}} -
- -
- - - {errors.zipCode && {errors.zipCode}} -
-
-
- -
-

Payment Information

-
- - - {errors.cardNumber && {errors.cardNumber}} -
- -
-
- - - {errors.expiryDate && {errors.expiryDate}} -
- -
- - - {errors.cvv && {errors.cvv}} -
-
-
- - -
- -
-

Order Summary

-
- {cartItems.map(item => ( -
- {item.name} x {item.quantity} - ${(item.price * item.quantity).toFixed(2)} -
- ))} -
-
-
- Subtotal: - ${total.toFixed(2)} -
-
- Shipping: - Free -
-
- Grand Total: - ${total.toFixed(2)} -
-
-
-
-
-
- ); -}; - -export default Checkout; \ No newline at end of file diff --git a/test_cases/src/pages/Home/Home.css b/test_cases/src/pages/Home/Home.css deleted file mode 100644 index cd4c7f1..0000000 --- a/test_cases/src/pages/Home/Home.css +++ /dev/null @@ -1,18 +0,0 @@ -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 1rem; -} - -.section-title { - text-align: center; - margin: 2rem 0; - color: #333; -} - -.categories { - display: flex; - justify-content: center; - flex-wrap: wrap; - margin-bottom: 2rem; -} \ No newline at end of file diff --git a/test_cases/src/pages/Home/Home.jsx b/test_cases/src/pages/Home/Home.jsx deleted file mode 100644 index 2fca150..0000000 --- a/test_cases/src/pages/Home/Home.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import Hero from '../../components/Hero/Hero'; -import Category from '../../components/Category/Category'; -import ProductList from '../../components/ProductList/ProductList'; -import './Home.css'; - -const Home = () => { - const [categories] = useState([ - { id: 1, name: 'Electronics', slug: 'electronics', image: 'https://images.unsplash.com/photo-1546868871-7041f2a55e12?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 2, name: 'Clothing', slug: 'clothing', image: 'https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 3, name: 'Home & Kitchen', slug: 'home-kitchen', image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 4, name: 'Books', slug: 'books', image: 'https://images.unsplash.com/photo-1544947950-fa07a98d237f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - ]); - - const [featuredProducts] = useState([ - { id: 1, name: 'Wireless Headphones', description: 'High-quality wireless headphones with noise cancellation', price: 129.99, image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 2, name: 'Smart Watch', description: 'Feature-rich smartwatch with health monitoring', price: 199.99, image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 3, name: 'Cotton T-Shirt', description: 'Comfortable cotton t-shirt for everyday wear', price: 24.99, image: 'https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - { id: 4, name: 'Coffee Maker', description: 'Automatic coffee maker with programmable timer', price: 89.99, image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80' }, - ]); - - return ( -
- - -
-

Shop by Category

-
- {categories.map(category => ( - - ))} -
- -

Featured Products

- -
-
- ); -}; - -export default Home; \ No newline at end of file diff --git a/test_cases/src/pages/Login/Login.css b/test_cases/src/pages/Login/Login.css deleted file mode 100644 index b9dce3f..0000000 --- a/test_cases/src/pages/Login/Login.css +++ /dev/null @@ -1,101 +0,0 @@ -.auth-page { - margin: 2rem 0; -} - -.auth-form { - max-width: 400px; - margin: 0 auto; - background-color: white; - border: 1px solid #ddd; - border-radius: 8px; - padding: 2rem; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.auth-title { - text-align: center; - margin-bottom: 2rem; - color: #333; -} - -.form-group { - margin-bottom: 1.5rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: #333; -} - -.form-group input { - width: 100%; - padding: 0.75rem; - border: 1px solid #ddd; - border-radius: 4px; - font-size: 1rem; -} - -.form-group input.error { - border-color: #dc3545; -} - -.error-message { - color: #dc3545; - font-size: 0.875rem; - margin-top: 0.25rem; - display: block; -} - -.submit-error { - background-color: #f8d7da; - color: #721c24; - padding: 0.75rem; - border-radius: 4px; - margin-bottom: 1rem; - text-align: center; -} - -.submit-btn { - width: 100%; - background-color: #007bff; - color: white; - border: none; - padding: 0.75rem; - border-radius: 4px; - font-size: 1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; -} - -.submit-btn:hover:not(:disabled) { - background-color: #0056b3; -} - -.submit-btn:disabled { - background-color: #6c757d; - cursor: not-allowed; -} - -.auth-links { - text-align: center; - margin-top: 1.5rem; -} - -.auth-links a { - color: #007bff; - text-decoration: none; -} - -.auth-links a:hover { - text-decoration: underline; -} - -@media (max-width: 768px) { - .auth-form { - margin: 1rem; - padding: 1.5rem; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/Login/Login.jsx b/test_cases/src/pages/Login/Login.jsx deleted file mode 100644 index 4a3c7a8..0000000 --- a/test_cases/src/pages/Login/Login.jsx +++ /dev/null @@ -1,131 +0,0 @@ -import React, { useState, useContext } from 'react'; -import { useNavigate, Link } from 'react-router-dom'; -import { AuthContext } from '../../context/AuthContext'; -import './Login.css'; - -const Login = () => { - const [formData, setFormData] = useState({ - email: '', - password: '' - }); - const [errors, setErrors] = useState({}); - const [isLoading, setIsLoading] = useState(false); - const { login } = useContext(AuthContext); - const navigate = useNavigate(); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData(prev => ({ - ...prev, - [name]: value - })); - - // Clear error when user starts typing - if (errors[name]) { - setErrors(prev => ({ - ...prev, - [name]: '' - })); - } - }; - - const validateForm = () => { - const newErrors = {}; - - if (!formData.email.trim()) { - newErrors.email = 'Email is required'; - } else if (!/\S+@\S+\.\S+/.test(formData.email)) { - newErrors.email = 'Email is invalid'; - } - - if (!formData.password) { - newErrors.password = 'Password is required'; - } else if (formData.password.length < 6) { - newErrors.password = 'Password must be at least 6 characters'; - } - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - - if (validateForm()) { - setIsLoading(true); - - // Simulate API call - try { - await new Promise(resolve => setTimeout(resolve, 1000)); - - // Mock successful login - const mockUser = { - id: 1, - name: 'John Doe', - email: formData.email - }; - - login(mockUser); - setIsLoading(false); - navigate('/'); - } catch (error) { - setIsLoading(false); - setErrors({ submit: 'Invalid email or password' }); - } - } - }; - - return ( -
-
-
-

Login to Your Account

- -
-
- - - {errors.email && {errors.email}} -
- -
- - - {errors.password && {errors.password}} -
- - {errors.submit &&
{errors.submit}
} - - -
- -
-

Don't have an account? Register here

-
-
-
-
- ); -}; - -export default Login; \ No newline at end of file diff --git a/test_cases/src/pages/ProductDetail/ProductDetail.css b/test_cases/src/pages/ProductDetail/ProductDetail.css deleted file mode 100644 index 4efe095..0000000 --- a/test_cases/src/pages/ProductDetail/ProductDetail.css +++ /dev/null @@ -1,141 +0,0 @@ -.product-detail { - margin-bottom: 2rem; -} - -.back-btn { - background: none; - border: 1px solid #007bff; - color: #007bff; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - font-weight: 500; - margin-bottom: 1rem; - transition: all 0.3s; -} - -.back-btn:hover { - background-color: #007bff; - color: white; -} - -.product-detail-content { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 2rem; - margin-top: 2rem; -} - -.product-image img { - width: 100%; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0,0,0,0.1); -} - -.product-info { - display: flex; - flex-direction: column; - justify-content: center; -} - -.product-name { - margin: 0 0 0.5rem 0; - color: #333; -} - -.product-category { - color: #666; - font-style: italic; - margin: 0 0 1rem 0; -} - -.product-price { - font-size: 2rem; - font-weight: bold; - color: #007bff; - margin: 1rem 0; -} - -.product-description { - color: #555; - line-height: 1.6; - margin-bottom: 2rem; -} - -.quantity-selector { - margin-bottom: 2rem; -} - -.quantity-selector label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: #333; -} - -.quantity-controls { - display: flex; - align-items: center; - gap: 0.5rem; -} - -.quantity-btn { - width: 40px; - height: 40px; - border: 1px solid #ddd; - background-color: #f8f9fa; - border-radius: 4px; - cursor: pointer; - font-weight: bold; - font-size: 1.2rem; -} - -.quantity-display { - min-width: 40px; - text-align: center; - font-size: 1.2rem; - font-weight: 500; -} - -.add-to-cart-btn { - background-color: #28a745; - color: white; - border: none; - padding: 1rem 2rem; - border-radius: 4px; - font-size: 1.1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; - width: 100%; -} - -.add-to-cart-btn:hover { - background-color: #218838; -} - -.loading, .error { - text-align: center; - padding: 2rem; - font-size: 1.1rem; -} - -.error { - color: #dc3545; -} - -@media (max-width: 768px) { - .product-detail-content { - grid-template-columns: 1fr; - gap: 1rem; - } - - .product-info { - align-items: center; - text-align: center; - } - - .quantity-controls { - justify-content: center; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/ProductDetail/ProductDetail.jsx b/test_cases/src/pages/ProductDetail/ProductDetail.jsx deleted file mode 100644 index e0afe55..0000000 --- a/test_cases/src/pages/ProductDetail/ProductDetail.jsx +++ /dev/null @@ -1,117 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { useCart } from '../../context/CartContext'; -import './ProductDetail.css'; - -const ProductDetail = () => { - const { id } = useParams(); - const navigate = useNavigate(); - const { addToCart } = useCart(); - const [product, setProduct] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [quantity, setQuantity] = useState(1); - - // Mock product data - const mockProducts = [ - { id: 1, name: 'Wireless Headphones', description: 'High-quality wireless headphones with noise cancellation. Perfect for music lovers and professionals alike.', price: 129.99, image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'electronics' }, - { id: 2, name: 'Smart Watch', description: 'Feature-rich smartwatch with health monitoring, GPS tracking, and smartphone integration.', price: 199.99, image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'electronics' }, - { id: 3, name: 'Cotton T-Shirt', description: 'Comfortable cotton t-shirt for everyday wear. Available in multiple colors and sizes.', price: 24.99, image: 'https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'clothing' }, - { id: 4, name: 'Coffee Maker', description: 'Automatic coffee maker with programmable timer and thermal carafe. Brew perfect coffee every time.', price: 89.99, image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'home-kitchen' }, - { id: 5, name: 'Bestseller Novel', description: 'Award-winning novel by popular author. A captivating story that keeps readers engaged from start to finish.', price: 14.99, image: 'https://images.unsplash.com/photo-1544947950-fa07a98d237f?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'books' }, - { id: 6, name: 'Bluetooth Speaker', description: 'Portable speaker with excellent sound quality and long battery life. Perfect for outdoor adventures.', price: 79.99, image: 'https://images.unsplash.com/photo-1546868871-7041f2a55e12?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'electronics' }, - { id: 7, name: 'Jeans', description: 'Classic fit jeans for casual wear. Made with premium denim for comfort and durability.', price: 59.99, image: 'https://images.unsplash.com/photo-1541099649105-f69ad21f3246?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'clothing' }, - { id: 8, name: 'Cookware Set', description: 'Complete cookware set for home cooking. Non-stick coating for easy cleaning and healthy cooking.', price: 149.99, image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80', category: 'home-kitchen' }, - ]; - - useEffect(() => { - // Simulate API call - const fetchProduct = () => { - try { - setTimeout(() => { - const foundProduct = mockProducts.find(p => p.id === parseInt(id)); - if (foundProduct) { - setProduct(foundProduct); - } else { - setError('Product not found'); - } - setLoading(false); - }, 500); - } catch (err) { - setError('Failed to load product'); - setLoading(false); - } - }; - - fetchProduct(); - }, [id]); - - const handleAddToCart = () => { - addToCart(product, quantity); - alert(`${quantity} ${product.name}(s) added to cart!`); - navigate('/cart'); - }; - - if (loading) { - return
Loading product...
; - } - - if (error) { - return
{error}
; - } - - if (!product) { - return
Product not found
; - } - - return ( -
-
- - -
-
- {product.name} -
- -
-

{product.name}

-

{product.category}

-
${product.price.toFixed(2)}
-

{product.description}

- -
- -
- - {quantity} - -
-
- - -
-
-
-
- ); -}; - -export default ProductDetail; \ No newline at end of file diff --git a/test_cases/src/pages/Products/Products.css b/test_cases/src/pages/Products/Products.css deleted file mode 100644 index 00a9799..0000000 --- a/test_cases/src/pages/Products/Products.css +++ /dev/null @@ -1,66 +0,0 @@ -.products-page { - margin-bottom: 2rem; -} - -.page-title { - text-align: center; - margin: 2rem 0; - color: #333; -} - -.filters { - text-align: center; - margin-bottom: 2rem; -} - -.filters h3 { - margin-bottom: 1rem; - color: #333; -} - -.category-filters { - display: flex; - justify-content: center; - flex-wrap: wrap; - gap: 0.5rem; -} - -.filter-btn { - background-color: #f8f9fa; - border: 1px solid #ddd; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - transition: all 0.3s; -} - -.filter-btn:hover { - background-color: #e9ecef; -} - -.filter-btn.active { - background-color: #007bff; - color: white; - border-color: #007bff; -} - -.loading, .error { - text-align: center; - padding: 2rem; - font-size: 1.1rem; -} - -.error { - color: #dc3545; -} - -@media (max-width: 768px) { - .category-filters { - flex-direction: column; - align-items: center; - } - - .filter-btn { - width: 80%; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/Products/Products.jsx b/test_cases/src/pages/Products/Products.jsx deleted file mode 100644 index f28e971..0000000 --- a/test_cases/src/pages/Products/Products.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import ProductList from '../../components/ProductList/ProductList'; -import './Products.css'; - -const Products = () => { - const [products, setProducts] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [selectedCategory, setSelectedCategory] = useState('all'); - - // Mock data for products - const mockProducts = [ - { id: 1, name: 'Wireless Headphones', description: 'High-quality wireless headphones with noise cancellation', price: 129.99, image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'electronics' }, - { id: 2, name: 'Smart Watch', description: 'Feature-rich smartwatch with health monitoring', price: 199.99, image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'electronics' }, - { id: 3, name: 'Cotton T-Shirt', description: 'Comfortable cotton t-shirt for everyday wear', price: 24.99, image: 'https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'clothing' }, - { id: 4, name: 'Coffee Maker', description: 'Automatic coffee maker with programmable timer', price: 89.99, image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'home-kitchen' }, - { id: 5, name: 'Bestseller Novel', description: 'Award-winning novel by popular author', price: 14.99, image: 'https://images.unsplash.com/photo-1544947950-fa07a98d237f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'books' }, - { id: 6, name: 'Bluetooth Speaker', description: 'Portable speaker with excellent sound quality', price: 79.99, image: 'https://images.unsplash.com/photo-1546868871-7041f2a55e12?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'electronics' }, - { id: 7, name: 'Jeans', description: 'Classic fit jeans for casual wear', price: 59.99, image: 'https://images.unsplash.com/photo-1541099649105-f69ad21f3246?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'clothing' }, - { id: 8, name: 'Cookware Set', description: 'Complete cookware set for home cooking', price: 149.99, image: 'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?ixlib=rb-4.0.3&auto=format&fit=crop&w=200&q=80', category: 'home-kitchen' }, - ]; - - const categories = [ - { id: 'all', name: 'All Products' }, - { id: 'electronics', name: 'Electronics' }, - { id: 'clothing', name: 'Clothing' }, - { id: 'home-kitchen', name: 'Home & Kitchen' }, - { id: 'books', name: 'Books' }, - ]; - - useEffect(() => { - // Simulate API call - const fetchProducts = () => { - try { - setTimeout(() => { - setProducts(mockProducts); - setLoading(false); - }, 500); - } catch (err) { - setError('Failed to load products'); - setLoading(false); - } - }; - - fetchProducts(); - }, []); - - const filteredProducts = selectedCategory === 'all' - ? products - : products.filter(product => product.category === selectedCategory); - - if (loading) { - return
Loading products...
; - } - - if (error) { - return
{error}
; - } - - return ( -
-
-

Our Products

- -
-

Filter by Category:

-
- {categories.map(category => ( - - ))} -
-
- - -
-
- ); -}; - -export default Products; \ No newline at end of file diff --git a/test_cases/src/pages/Register/Register.css b/test_cases/src/pages/Register/Register.css deleted file mode 100644 index 422ab1b..0000000 --- a/test_cases/src/pages/Register/Register.css +++ /dev/null @@ -1,112 +0,0 @@ -.auth-page { - margin: 2rem 0; -} - -.auth-form { - max-width: 400px; - margin: 0 auto; - background-color: white; - border: 1px solid #ddd; - border-radius: 8px; - padding: 2rem; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.auth-title { - text-align: center; - margin-bottom: 2rem; - color: #333; -} - -.form-row { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1rem; - margin-bottom: 1.5rem; -} - -.form-group { - margin-bottom: 1.5rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: #333; -} - -.form-group input { - width: 100%; - padding: 0.75rem; - border: 1px solid #ddd; - border-radius: 4px; - font-size: 1rem; -} - -.form-group input.error { - border-color: #dc3545; -} - -.error-message { - color: #dc3545; - font-size: 0.875rem; - margin-top: 0.25rem; - display: block; -} - -.submit-error { - background-color: #f8d7da; - color: #721c24; - padding: 0.75rem; - border-radius: 4px; - margin-bottom: 1rem; - text-align: center; -} - -.submit-btn { - width: 100%; - background-color: #28a745; - color: white; - border: none; - padding: 0.75rem; - border-radius: 4px; - font-size: 1rem; - font-weight: 500; - cursor: pointer; - transition: background-color 0.3s; -} - -.submit-btn:hover:not(:disabled) { - background-color: #218838; -} - -.submit-btn:disabled { - background-color: #6c757d; - cursor: not-allowed; -} - -.auth-links { - text-align: center; - margin-top: 1.5rem; -} - -.auth-links a { - color: #007bff; - text-decoration: none; -} - -.auth-links a:hover { - text-decoration: underline; -} - -@media (max-width: 768px) { - .auth-form { - margin: 1rem; - padding: 1.5rem; - } - - .form-row { - grid-template-columns: 1fr; - } -} \ No newline at end of file diff --git a/test_cases/src/pages/Register/Register.jsx b/test_cases/src/pages/Register/Register.jsx deleted file mode 100644 index 9e3d4aa..0000000 --- a/test_cases/src/pages/Register/Register.jsx +++ /dev/null @@ -1,179 +0,0 @@ -import React, { useState } from 'react'; -import { useNavigate, Link } from 'react-router-dom'; -import './Register.css'; - -const Register = () => { - const [formData, setFormData] = useState({ - firstName: '', - lastName: '', - email: '', - password: '', - confirmPassword: '' - }); - const [errors, setErrors] = useState({}); - const [isLoading, setIsLoading] = useState(false); - const navigate = useNavigate(); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData(prev => ({ - ...prev, - [name]: value - })); - - // Clear error when user starts typing - if (errors[name]) { - setErrors(prev => ({ - ...prev, - [name]: '' - })); - } - }; - - const validateForm = () => { - const newErrors = {}; - - if (!formData.firstName.trim()) { - newErrors.firstName = 'First name is required'; - } - - if (!formData.lastName.trim()) { - newErrors.lastName = 'Last name is required'; - } - - if (!formData.email.trim()) { - newErrors.email = 'Email is required'; - } else if (!/\S+@\S+\.\S+/.test(formData.email)) { - newErrors.email = 'Email is invalid'; - } - - if (!formData.password) { - newErrors.password = 'Password is required'; - } else if (formData.password.length < 6) { - newErrors.password = 'Password must be at least 6 characters'; - } - - if (formData.password !== formData.confirmPassword) { - newErrors.confirmPassword = 'Passwords do not match'; - } - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - - if (validateForm()) { - setIsLoading(true); - - // Simulate API call - try { - await new Promise(resolve => setTimeout(resolve, 1000)); - - // Mock successful registration - setIsLoading(false); - alert('Registration successful! Please log in.'); - navigate('/login'); - } catch (error) { - setIsLoading(false); - setErrors({ submit: 'Registration failed. Please try again.' }); - } - } - }; - - return ( -
-
-
-

Create an Account

- -
-
-
- - - {errors.firstName && {errors.firstName}} -
- -
- - - {errors.lastName && {errors.lastName}} -
-
- -
- - - {errors.email && {errors.email}} -
- -
- - - {errors.password && {errors.password}} -
- -
- - - {errors.confirmPassword && {errors.confirmPassword}} -
- - {errors.submit &&
{errors.submit}
} - - -
- -
-

Already have an account? Sign in here

-
-
-
-
- ); -}; - -export default Register; \ No newline at end of file diff --git a/test_cases/src/styles/globals.css b/test_cases/src/styles/globals.css deleted file mode 100644 index da178f6..0000000 --- a/test_cases/src/styles/globals.css +++ /dev/null @@ -1,53 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - line-height: 1.6; - color: #333; - background-color: #f5f5f5; -} - -a { - text-decoration: none; - color: inherit; -} - -ul { - list-style: none; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 1rem; -} - -.main-content { - min-height: calc(100vh - 120px); - padding: 1rem 0; -} - -.app { - min-height: 100vh; - display: flex; - flex-direction: column; -} - -button { - cursor: pointer; - font-family: inherit; -} - -input { - font-family: inherit; -} - -@media (max-width: 768px) { - .container { - padding: 0 0.5rem; - } -} \ No newline at end of file