# MVC Webshop Application A pure JavaScript implementation of a webshop using the Model-View-Controller (MVC) architectural pattern. This educational project demonstrates core web development concepts without external frameworks. ## ๐Ÿ—๏ธ Architecture Overview This application follows the MVC pattern with a centralized view rendering system: - **Model**: Handles data management and business logic - **View**: Manages HTML generation and DOM manipulation - **Controller**: Coordinates user interactions and data flow ## ๐Ÿ“Š UML Diagrams ### Class Diagram ```mermaid classDiagram class Model { -products: Array~Product~ -cart: Array~CartItem~ +getAllProducts() Array~Product~ +getProductById(id) Product +addToCart(productId, quantity) boolean +removeFromCart(productId) void +updateCartQuantity(productId, quantity) void +getCart() Array~CartItem~ +getCartTotal() number +getCartItemCount() number +clearCart() void +saveCartToStorage() void +loadCartFromStorage() Array~CartItem~ +initializeCart() void } class View { -currentPage: string -cartCount: number +updateView(viewType, data) void +generateNavbar() string +generateProductsPage(products) string +generateProductDetailPage(product) string +generateCartPage(cartItems, total, itemCount) string +createProductCard(product) string +createCartItem(item) string +attachEventListeners() void +updateCartCountInNav() void +showNotification(message) void } class Controller { +loadProducts() void +showProductDetail(productId) void +handleAddToCart(productId) void +handleRemoveFromCart(productId) void +changeQuantity(productId, change) void +handleClearCart() void +navigateToProducts() void +navigateToCart() void +updateCartDisplay() void } class Product { +id: number +name: string +price: number +description: string +image: string +category: string } class CartItem { +productId: number +quantity: number +product: Product } class App { +initialize() void } Controller --> Model : uses Controller --> View : updates View --> Controller : sends events Model --> Product : contains Model --> CartItem : manages CartItem --> Product : references App --> Controller : initializes App --> Model : sets up App --> View : starts ``` ### Sequence Diagram - Add to Cart Flow ```mermaid sequenceDiagram participant U as User participant V as View participant C as Controller participant M as Model U->>V: Click "Add to Cart" V->>C: handleAddToCart(productId) C->>M: addToCart(productId) M->>M: getProductById(productId) M->>M: Find existing item or create new M->>M: saveCartToStorage() M-->>C: return true/false alt Success C->>M: getProductById(productId) M-->>C: return product C->>V: updateView('notification', {message}) C->>C: updateCartDisplay() C->>M: getCart() M-->>C: return cart C->>M: getCartTotal() M-->>C: return total C->>M: getCartItemCount() M-->>C: return itemCount C->>V: updateView('cart', {cartItems, total, itemCount}) C->>V: updateView('cart-count', {count}) V->>V: generateCartPage() or updateCartCountInNav() V-->>U: Updated UI with notification else Failure C->>V: updateView('notification', {message: 'Error'}) V-->>U: Error message end ``` ## ๐Ÿ“ Project Structure ``` mvc-emne2/ โ”œโ”€โ”€ index.html # Main HTML file with single app container โ”œโ”€โ”€ styles.css # Application styling โ”œโ”€โ”€ js/ โ”‚ โ”œโ”€โ”€ app.js # Application initialization โ”‚ โ”œโ”€โ”€ model.js # Data layer and business logic โ”‚ โ”œโ”€โ”€ view.js # UI rendering and HTML generation โ”‚ โ””โ”€โ”€ controller.js # User interaction handling โ”œโ”€โ”€ flow-diagram.md # Application flow visualization โ””โ”€โ”€ README.md # This documentation ``` ## ๐Ÿ”ง Key Components ### 1. Model (`model.js`) **Purpose**: Manages application data and persistence **Key Functions**: - `getAllProducts()` - Returns product catalog - `getProductById(id)` - Retrieves specific product - `addToCart(productId, quantity)` - Adds items to cart - `removeFromCart(productId)` - Removes items from cart - `updateCartQuantity(productId, quantity)` - Updates item quantities - `getCart()` - Returns current cart contents - `getCartTotal()` - Calculates cart total price - `getCartItemCount()` - Returns total item count - `clearCart()` - Empties the cart - `saveCartToStorage()` / `loadCartFromStorage()` - LocalStorage persistence **Data Structure**: ```javascript // Product { id: number, name: string, price: number, description: string, image: string (emoji), category: string } // Cart Item { productId: number, quantity: number, product: Product } ``` ### 2. View (`view.js`) **Purpose**: Handles all UI rendering through a centralized `updateView` function **Core Architecture**: ```javascript function updateView(viewType, data = {}) { switch (viewType) { case 'products': // Render product listing case 'product-detail': // Render single product case 'cart': // Render shopping cart case 'cart-count': // Update cart badge case 'notification': // Show user messages } } ``` **Key Features**: - **Single Entry Point**: All rendering goes through `updateView()` - **Complete Page Generation**: Generates entire page HTML including navigation - **Event Listener Management**: Automatically attaches event listeners after each render - **Template Functions**: Modular HTML generation functions **HTML Generation Functions**: - `generateNavbar()` - Creates navigation header - `generateProductsPage(products)` - Product listing page - `generateProductDetailPage(product)` - Product detail page - `generateCartPage(cartItems, total, itemCount)` - Shopping cart page - `createProductCard(product)` - Individual product card - `createCartItem(item)` - Individual cart item ### 3. Controller (`controller.js`) **Purpose**: Handles user interactions and coordinates between Model and View **Navigation Functions**: - `navigateToProducts()` - Shows product listing - `navigateToCart()` - Shows shopping cart - `showProductDetail(productId)` - Shows product details **Cart Management**: - `handleAddToCart(productId)` - Adds product to cart - `handleRemoveFromCart(productId)` - Removes product from cart - `changeQuantity(productId, change)` - Updates product quantity - `handleClearCart()` - Empties entire cart - `updateCartDisplay()` - Refreshes cart view and counter **Key Design Patterns**: - All functions call `updateView()` for UI updates - User notifications are handled consistently - Cart state is automatically persisted after changes ### 4. Application Initialization (`app.js`) **Purpose**: Bootstraps the application **Initialization Flow**: 1. Wait for DOM to load 2. Initialize cart from localStorage 3. Load products from model 4. Render initial products page 5. Update cart counter ```javascript document.addEventListener('DOMContentLoaded', function() { initializeCart(); const products = getAllProducts(); const itemCount = getCartItemCount(); updateView('products', { products }); updateView('cart-count', { count: itemCount }); console.log('Nettbutikk MVC Demo initialisert!'); }); ``` ## ๐Ÿ”„ Data Flow ### 1. Application Startup ``` HTML Load โ†’ DOMContentLoaded โ†’ initializeCart() โ†’ loadCartFromStorage() โ†’ getAllProducts() โ†’ updateView('products') โ†’ generateProductsPage() โ†’ attachEventListeners() ``` ### 2. User Interactions ``` User Click โ†’ Controller Function โ†’ Model Operation โ†’ updateView() โ†’ HTML Generation โ†’ Event Listener Attachment โ†’ UI Update ``` ### 3. Cart Operations ``` Add to Cart โ†’ addToCart() โ†’ saveCartToStorage() โ†’ updateCartDisplay() โ†’ updateView('cart') + updateView('cart-count') โ†’ showNotification() ``` ## ๐ŸŽจ View Rendering System ### Centralized Rendering All UI updates flow through the single `updateView()` function: ```javascript updateView('products', { products: [...] }); updateView('product-detail', { product: {...} }); updateView('cart', { cartItems: [...], total: 0, itemCount: 0 }); updateView('cart-count', { count: 0 }); updateView('notification', { message: 'Success!' }); ``` ### Complete Page Generation Unlike traditional DOM manipulation, this system generates complete page HTML: ```javascript function generateProductsPage(products) { return ` ${generateNavbar()}

Vรฅre Produkter

${products.map(product => createProductCard(product)).join('')}
`; } ``` ### Event Listener Management After each render, event listeners are reattached: ```javascript function attachEventListeners() { const productsLink = document.querySelector('[data-page="products"]'); const cartLink = document.querySelector('[data-page="cart"]'); if (productsLink) { productsLink.addEventListener('click', function(e) { e.preventDefault(); navigateToProducts(); }); } // ... more listeners } ``` ## ๐Ÿ’พ Data Persistence ### LocalStorage Integration Cart data is automatically persisted: ```javascript function saveCartToStorage() { try { localStorage.setItem('webstore_cart', JSON.stringify(cart)); } catch (error) { console.error('Feil ved lagring av handlekurv til localStorage:', error); } } function loadCartFromStorage() { try { const savedCart = localStorage.getItem('webstore_cart'); if (savedCart) { const parsedCart = JSON.parse(savedCart); return parsedCart.map(item => ({ ...item, product: products.find(p => p.id === item.productId) || { id: item.productId, name: 'Ukjent Produkt', price: 0 } })); } } catch (error) { console.error('Feil ved lasting av handlekurv fra localStorage:', error); } return []; } ``` ## ๐Ÿš€ Usage ### Running the Application 1. Open `index.html` in a web browser 2. The application initializes automatically 3. Navigate between products, product details, and cart 4. Cart state persists across browser sessions ### Key Features - **Product Browsing**: View all products in a grid layout - **Product Details**: Click any product for detailed view - **Shopping Cart**: Add, remove, and modify quantities - **Persistent Cart**: Cart contents saved in localStorage - **Responsive Design**: Works on desktop and mobile - **User Notifications**: Feedback for all user actions ## ๐ŸŽฏ Educational Benefits ### MVC Pattern Demonstration - Clear separation of concerns - Model handles data, View handles presentation, Controller handles logic - Demonstrates how components interact in MVC architecture ### Modern JavaScript Features - ES6+ syntax (arrow functions, template literals, destructuring) - LocalStorage API usage - Event handling patterns - Functional programming concepts ### Web Development Fundamentals - DOM manipulation techniques - Event listener management - Client-side state management - HTML generation and templating - CSS styling integration ## ๐Ÿ”ง Technical Decisions ### Why Centralized Rendering? - **Consistency**: All UI updates follow the same pattern - **Maintainability**: Easy to track and debug UI changes - **Scalability**: Simple to add new view types - **State Management**: Clear data flow from model to view ### Why Complete Page Generation? - **Simplicity**: No complex DOM diffing or state tracking - **Reliability**: Fresh render eliminates stale state issues - **Performance**: Modern browsers handle innerHTML efficiently - **Debugging**: Easy to see exactly what HTML is generated ### Why LocalStorage? - **Persistence**: Cart survives browser restarts - **Simplicity**: No server-side complexity - **Performance**: Instant load times - **Educational**: Demonstrates client-side storage concepts ## ๐ŸŽจ Styling Architecture The application uses a clean, modern CSS design: - Responsive grid layouts - Card-based product display - Consistent button and form styling - Mobile-friendly navigation - Smooth transitions and hover effects ## ๐Ÿ”ฎ Future Enhancements This MVC implementation serves as a foundation for progressive enhancement: 1. **Phase 2**: Add TypeScript for type safety 2. **Phase 3**: Implement Vue.js for reactive UI 3. **Phase 4**: Add user authentication 4. **Phase 5**: Integrate payment processing 5. **Phase 6**: Add product search and filtering 6. **Phase 7**: Implement real backend API ## ๐Ÿ“š Learning Outcomes By studying this codebase, you'll understand: - MVC architectural pattern implementation - Client-side state management techniques - Modern JavaScript development practices - HTML generation and templating approaches - Event-driven programming patterns - LocalStorage API usage - Responsive web design principles --- *This project is part of the GET Frontend Development curriculum, demonstrating core web development concepts through practical implementation.*