# Frontend JavaScript Documentation

This documentation covers all the JavaScript utilities and helpers available in the Store application.

## Table of Contents

1. [Frontend.js](#frontendjs) - Main frontend interactivity
2. [Cart.js](#cartjs) - Shopping cart management
3. [Forms.js](#formsjs) - Form handling and validation
4. [Usage Examples](#usage-examples)

---

## Frontend.js

Main JavaScript file containing core functionality for the frontend.

### Initialization

The file automatically initializes on page load:
```javascript
document.addEventListener('DOMContentLoaded', function() {
    initializeEventListeners();
    initializeSmoothScroll();
    initializeAnimations();
    initializeFormValidation();
});
```

### Key Functions

#### `showToast(message, type)`
Display a dismissible toast notification.

**Parameters:**
- `message` (string) - The notification message
- `type` (string) - One of: 'success', 'danger', 'warning', 'info'

**Example:**
```javascript
showToast('Item added to cart!', 'success');
showToast('An error occurred', 'danger');
```

#### `changeProductImage(imagePath, productName)`
Change the displayed product image in product detail view.

**Parameters:**
- `imagePath` (string) - URL to the new image
- `productName` (string) - Product name for alt text

**Example:**
```html
<img id="mainImage" src="image.jpg" alt="Product">
<button onclick="changeProductImage('/path/to/image.jpg', 'Product Name')">
    View Image
</button>
```

#### `updateCartCount(count)`
Update the cart badge count in the navbar.

**Parameters:**
- `count` (number) - Number of items in cart

**Example:**
```javascript
updateCartCount(5); // Shows "5" in cart badge
updateCartCount(0); // Hides the badge
```

#### `addToWishlist(productId)`
Add a product to user's wishlist.

**Parameters:**
- `productId` (number) - ID of the product

**Example:**
```javascript
addToWishlist(123);
```

#### `shareProduct(productId, productName)`
Share product via native share API or copy link to clipboard.

**Parameters:**
- `productId` (number) - Product ID
- `productName` (string) - Product name

**Example:**
```javascript
shareProduct(123, 'Amazing Product');
```

#### `formatPrice(price)`
Format a number as currency (USD).

**Parameters:**
- `price` (number) - Price to format

**Example:**
```javascript
formatPrice(99.99); // Returns $99.99
```

### Event Listeners

- **Mobile menu auto-close** - Navbar collapses when a link is clicked
- **Alert auto-dismiss** - Alerts dismiss automatically after 5 seconds
- **Add to cart confirmation** - Shows toast when item is added

### Animations

Elements with classes `.product-card`, `.card`, or `.section-title` are animated when scrolling into view using Intersection Observer.

### Scroll Effects

The navbar shadow changes dynamically based on scroll position:
- Below 50px scroll: Lighter shadow
- Above 50px scroll: Darker shadow

---

## Cart.js

Shopping cart management class with local storage persistence.

### Usage

The cart is automatically initialized as a global variable:
```javascript
// Access the cart
cart.addItem(productId, productName, price, quantity);
cart.removeItem(productId);
cart.getItemCount();
cart.getSubtotal();
```

### ShoppingCart Class

#### Constructor
```javascript
const cart = new ShoppingCart();
```

#### Methods

**`addItem(productId, productName, price, quantity)`**
Add item to cart.

```javascript
cart.addItem(123, 'Product Name', 99.99, 1);
// Shows: "Product Name added to cart!"
```

**`removeItem(productId)`**
Remove item from cart.

```javascript
cart.removeItem(123);
```

**`updateQuantity(productId, quantity)`**
Update item quantity (removes if quantity <= 0).

```javascript
cart.updateQuantity(123, 5);
```

**`getItems()`**
Get all cart items.

```javascript
const items = cart.getItems();
// Returns: { 123: { id, name, price, quantity }, ... }
```

**`getItemCount()`**
Get total number of items in cart.

```javascript
const count = cart.getItemCount(); // 0-n
```

**`getSubtotal()`**
Get total price of all items.

```javascript
const total = cart.getSubtotal(); // Returns number
```

**`getItem(productId)`**
Get specific item details.

```javascript
const item = cart.getItem(123);
// Returns: { id: 123, name: '...', price: 99.99, quantity: 2 }
```

**`clear()`**
Empty the entire cart.

```javascript
cart.clear();
```

**`isEmpty()`**
Check if cart is empty.

```javascript
if (cart.isEmpty()) {
    console.log('Cart is empty');
}
```

**`export()`**
Export cart data for submission.

```javascript
const cartData = cart.export();
// Returns: { items, total, itemCount, timestamp }
```

### HTML Integration

**Add to Cart Button:**
```html
<button class="btn btn-primary" 
        data-add-to-cart
        data-product-id="123"
        data-product-name="Product Name"
        data-product-price="99.99"
        data-quantity="1">
    Add to Cart
</button>
```

**Cart Summary Elements:**
```html
<span data-subtotal>$0.00</span>
<span data-total>$0.00</span>
<span data-cart-count style="display:none;">0</span>
```

**Cart Items Table:**
```html
<table>
    <tbody data-cart-items">
        <!-- Items rendered here -->
    </tbody>
</table>
```

---

## Forms.js

Comprehensive form handling with validation and AJAX submission.

### FormHandler Class

Basic form validation without AJAX.

**Usage:**
```javascript
const handler = new FormHandler('#myForm');
```

#### Methods

**`validate()`**
Validate all form fields.

```javascript
if (handler.validate()) {
    console.log('Form is valid');
}
```

**`validateField(field)`**
Validate a specific field.

```javascript
const field = document.querySelector('input[name="email"]');
handler.validateField(field);
```

**`reset()`**
Reset form and clear validation states.

```javascript
handler.reset();
```

**`getData()`**
Get form data as object.

```javascript
const data = handler.getData();
// Returns: { field1: 'value1', field2: 'value2', ... }
```

**`getFormData()`**
Get form data as FormData object.

```javascript
const formData = handler.getFormData();
// Can be used with fetch() API
```

### Field Validation

Automatic validation for:
- **Required fields** - `required` attribute
- **Email fields** - `type="email"`
- **Min length** - `minlength` attribute
- **Max length** - `maxlength` attribute
- **URL fields** - `type="url"`
- **Number fields** - `type="number"` with min/max
- **Pattern matching** - `pattern` attribute

**HTML Example:**
```html
<form>
    <input type="email" name="email" required class="form-control">
    <input type="text" name="username" minlength="3" maxlength="20" required class="form-control">
    <input type="number" name="age" min="18" max="120" required class="form-control">
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
```

### AjaxFormHandler Class

Form handler with AJAX submission.

**Usage:**
```javascript
const handler = new AjaxFormHandler('#myForm', {
    url: '/api/submit',
    method: 'POST',
    redirectOn: 'redirect_url',
    onSuccess: function(data) {
        console.log('Success!', data);
    },
    onError: function(data) {
        console.log('Error!', data);
    }
});
```

#### Options

- `url` (string) - Submission endpoint
- `method` (string) - HTTP method (POST, PUT, etc.)
- `redirectOn` (string) - Redirect to URL in response field
- `onSuccess` (function) - Callback on success
- `onError` (function) - Callback on error
- `showMessages` (boolean) - Show toast messages (default: true)

#### Example Usage

```javascript
new AjaxFormHandler('#contactForm', {
    url: '/contact/send',
    method: 'POST',
    onSuccess: function(data) {
        showToast('Message sent successfully!', 'success');
        this.reset();
    },
    onError: function(data) {
        if (data.errors) {
            console.log('Validation errors:', data.errors);
        }
    }
});
```

### ContactFormHandler Class

Pre-configured handler for contact forms.

```html
<form data-form="contact">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    <textarea name="message" required></textarea>
    <button type="submit">Send</button>
</form>

<script>
    // Automatically initialized if form exists
</script>
```

### ReviewFormHandler Class

Pre-configured handler for product reviews.

```html
<form data-form="review" data-product-id="123">
    <div class="mb-3">
        <label class="form-label">Rating</label>
        <div>
            <input type="radio" name="rating" value="5" id="rating5">
            <label for="rating5">★★★★★</label>
        </div>
        <div data-rating-display>☆☆☆☆☆</div>
    </div>
    
    <input type="text" name="title" placeholder="Review Title" required>
    <textarea name="content" placeholder="Your review..." required></textarea>
    <button type="submit">Submit Review</button>
</form>

<script>
    // Automatically initialized if form exists
</script>
```

---

## Usage Examples

### Example 1: Complete Product Page

```html
<div class="product-detail">
    <!-- Main Image -->
    <img id="mainImage" src="{{ $product->getPrimaryImage()->image_path }}" alt="{{ $product->name }}">
    
    <!-- Thumbnail Gallery -->
    <div class="gallery-thumbnails">
        @foreach($product->productImages as $image)
            <img src="{{ $image->image_path }}" 
                 alt="{{ $product->name }}"
                 onclick="changeProductImage('{{ $image->image_path }}', '{{ $product->name }}')">
        @endforeach
    </div>
    
    <!-- Add to Cart -->
    <button class="btn btn-primary btn-lg"
            data-add-to-cart
            data-product-id="{{ $product->id }}"
            data-product-name="{{ $product->name }}"
            data-product-price="{{ $product->price }}"
            data-quantity="1">
        <i class="bi bi-cart-plus"></i> Add to Cart
    </button>
    
    <!-- Share Button -->
    <button class="btn btn-outline-primary"
            onclick="shareProduct({{ $product->id }}, '{{ $product->name }}')">
        <i class="bi bi-share"></i> Share
    </button>

    <!-- Reviews Section -->
    <div data-reviews-section>
        <h3>Customer Reviews</h3>
        @foreach($product->reviews as $review)
            <div class="review-item">
                <div>Rating: {{ $review->rating }}/5</div>
                <h5>{{ $review->title }}</h5>
                <p>{{ $review->content }}</p>
                <small>by {{ $review->user->name }}</small>
            </div>
        @endforeach

        <!-- Review Form -->
        @auth
            <form data-form="review" data-product-id="{{ $product->id }}">
                @csrf
                <h5>Leave a Review</h5>
                
                <div class="mb-3">
                    <label class="form-label">Rating (1-5 stars)</label>
                    <div data-rating-display>☆☆☆☆☆</div>
                    <div>
                        @for($i = 1; $i <= 5; $i++)
                            <input type="radio" name="rating" value="{{ $i }}" id="rating{{ $i }}" required>
                            <label for="rating{{ $i }}">{{ $i }}</label>
                        @endfor
                    </div>
                </div>

                <input type="text" name="title" placeholder="Review Title" 
                       required class="form-control mb-3"
                       minlength="5" maxlength="100">

                <textarea name="content" placeholder="Share your experience..." 
                          required class="form-control mb-3"
                          minlength="10" maxlength="1000" rows="5"></textarea>

                <button type="submit" class="btn btn-primary">Submit Review</button>
            </form>
        @else
            <p><a href="{{ route('login') }}">Login</a> to leave a review</p>
        @endauth
    </div>
</div>
```

### Example 2: Shopping Cart Page

```html
<div class="cart-container">
    <h1>Shopping Cart</h1>

    <table class="table">
        <thead>
            <tr>
                <th>Product</th>
                <th>Price</th>
                <th>Quantity</th>
                <th>Total</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody data-cart-items>
            <!-- Items automatically rendered by cart.js -->
        </tbody>
    </table>

    <div class="row mt-4">
        <div class="col-md-6 ms-auto">
            <div class="card">
                <div class="card-body">
                    <h5>Order Summary</h5>
                    <div class="d-flex justify-content-between mb-2">
                        <span>Subtotal:</span>
                        <span data-subtotal>$0.00</span>
                    </div>
                    <div class="d-flex justify-content-between mb-2">
                        <span>Tax (10%):</span>
                        <span id="taxAmount">$0.00</span>
                    </div>
                    <hr>
                    <div class="d-flex justify-content-between">
                        <strong>Total:</strong>
                        <strong data-total>$0.00</strong>
                    </div>
                    <button class="btn btn-success btn-lg w-100 mt-3">Proceed to Checkout</button>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    // Cart is automatically managed by cart.js
    // Just use HTML data attributes
</script>
```

### Example 3: Contact Form

```html
<form data-form="contact" class="contact-form">
    @csrf
    
    <div class="mb-3">
        <label class="form-label" for="name">Full Name</label>
        <input type="text" class="form-control" id="name" name="name" 
               required minlength="3" maxlength="100">
    </div>

    <div class="mb-3">
        <label class="form-label" for="email">Email Address</label>
        <input type="email" class="form-control" id="email" name="email" required>
    </div>

    <div class="mb-3">
        <label class="form-label" for="subject">Subject</label>
        <input type="text" class="form-control" id="subject" name="subject" 
               required minlength="5" maxlength="100">
    </div>

    <div class="mb-3">
        <label class="form-label" for="message">Message</label>
        <textarea class="form-control" id="message" name="message" 
                  required minlength="10" maxlength="1000" rows="5"></textarea>
    </div>

    <button type="submit" class="btn btn-primary">Send Message</button>
</form>

<!-- Auto-initialized by forms.js -->
```

### Example 4: Wishlist Page

```html
<button onclick="addToWishlist({{ $product->id }});" 
        class="btn btn-outline-danger">
    <i class="bi bi-heart"></i> Add to Wishlist
</button>
```

### Example 5: Product Search with Price Format

```javascript
// In your JavaScript code
const products = [
    { id: 1, name: 'Product 1', price: 99.99 },
    { id: 2, name: 'Product 2', price: 199.99 }
];

products.forEach(product => {
    console.log(`${product.name}: ${formatPrice(product.price)}`);
    // Output:
    // Product 1: $99.99
    // Product 2: $199.99
});
```

---

## Browser Support

- Chrome / Edge 90+
- Firefox 88+
- Safari 14+
- Mobile browsers (iOS Safari 14+, Chrome Mobile)

## Performance Notes

- Uses Intersection Observer for efficient scroll animations
- Debounce/throttle functions for smooth scroll effects
- LocalStorage for cart persistence (no server calls needed)
- AJAX forms prevent full page reloads
- CSS transitions for smooth animations

## Troubleshooting

**Issue:** Cart not persisting
- Solution: Check browser LocalStorage is enabled
- Check console for JavaScript errors

**Issue:** Form validation not working
- Solution: Ensure form fields have proper `required`, `type`, or `minlength` attributes
- Check that field names match your backend validation

**Issue:** Toast notifications not showing
- Solution: Ensure `showToast()` function is called with valid type
- Check Bootstrap CSS is loaded

**Issue:** Images not changing in gallery
- Solution: Ensure `id="mainImage"` exists on main image element
- Check image paths are correct and accessible

---

## Future Enhancements

- Dark mode toggle
- Keyboard shortcuts for search
- Image lazy loading
- Advanced filtering with AJAX
- User preference storage (language, theme)
- PWA offline support
- Product comparison functionality

